
using System.Collections.Concurrent;
using System.Collections.Generic;

namespace ThingsGateway.Foundation
{
    /// <summary>
    /// 依赖属性的集合操作类接口.
    /// </summary>
    public interface IDependencyObject : IDisposable
    {

        #region Public Methods

        /// <summary>
        /// 获取依赖注入的值
        /// </summary>
        /// <param name="dp"></param>
        /// <returns></returns>
        object GetValue(DependencyProperty dp);

        /// <summary>
        /// 获取依赖注入的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dp"></param>
        /// <returns></returns>
        public T GetValue<T>(DependencyProperty dp);

        KeyValuePair<DependencyProperty, object>[] GetValueClone();

        /// <summary>
        /// 设置依赖注入的值
        /// </summary>
        /// <param name="dp"></param>
        /// <param name="value"></param>
        public DependencyObject SetValue(DependencyProperty dp, object value);

        #endregion Public Methods

    }

    /// <summary>
    /// 内置依赖属性集合的操作类.
    /// 线程安全。
    /// </summary>
    public class DependencyObject : DisposableObject, IDependencyObject, IDisposable
    {

        #region Private Fields

        [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
        private readonly ConcurrentDictionary<DependencyProperty, object> m_dp;

        #endregion Private Fields

        #region Public Constructors

        /// <summary>
        /// 构造函数
        /// </summary>
        public DependencyObject()
        {
            m_dp = new ConcurrentDictionary<DependencyProperty, object>();
        }

        #endregion Public Constructors

        #region Public Methods

        /// <summary>
        /// 获取依赖注入的值
        /// </summary>
        /// <param name="dp"></param>
        /// <returns></returns>
        public object GetValue(DependencyProperty dp)
        {
            if (m_dp.TryGetValue(dp, out object value))
            {
                return value;
            }
            else
            {
                return dp.DefauleValue;
            }
        }

        /// <summary>
        /// 获取依赖注入的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dp"></param>
        /// <returns></returns>
        public T GetValue<T>(DependencyProperty dp)
        {
            try
            {
                return (T)GetValue(dp);
            }
            catch
            {
                return default;
            }
        }

        public KeyValuePair<DependencyProperty, object>[] GetValueClone()
        {
            return m_dp.ToArray();
        }

        /// <summary>
        /// 设置依赖注入的值
        /// </summary>
        /// <param name="dp"></param>
        /// <param name="value"></param>
        public DependencyObject SetValue(DependencyProperty dp, object value)
        {
            dp.DataValidation(value);
            if (m_dp.ContainsKey(dp))
            {
                m_dp[dp] = value;
            }
            else
            {
                m_dp.TryAdd(dp, value);
            }
            return this;
        }

        #endregion Public Methods

        #region Protected Methods

        protected override void Dispose(bool disposing)
        {
            m_dp.Clear();
            base.Dispose(disposing);
        }

        #endregion Protected Methods

    }
}